/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.pb138.videodes.impl;

import cz.muni.fi.pb138.videodes.entity.Dvd;
import cz.muni.fi.pb138.videodes.entity.DvdType;
import cz.muni.fi.pb138.videodes.entity.Genre;
import cz.muni.fi.pb138.videodes.entity.Movie;
import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.odftoolkit.odfdom.doc.OdfDocument;
import org.odftoolkit.odfdom.doc.table.OdfTable;

/**
 * This class provides functionality for importing DVDs and movies to the database.
 *
 * @author vaclav
 */
public class ImportFromODS {

    private OdfDocument odfDocument;

    /**
     * Private constructor which set the attribute document
     * 
     * @param document 
     */
    private ImportFromODS(OdfDocument odfDocument) {
        this.odfDocument = odfDocument;
    }

    /**
     * Creates new instance of this class.
     * 
     * @param file an ODF file
     */
    public static ImportFromODS newInstance(File file) throws Exception {
        OdfDocument odfDocument = OdfDocument.loadDocument(file);

        return new ImportFromODS(odfDocument);
    }

    /**
     * Executes the importation to the database.
     */
    public void importToDatabase() {
        List<OdfTable> sheets = odfDocument.getTableList();
        List<Dvd> dvds = new ArrayList<Dvd>();
        List<Movie> movies = new ArrayList<Movie>();

        try {
            for (int i = 0; i < sheets.size(); i++) {
                OdfTable table = sheets.get(i);

                if (table.getTableName().equalsIgnoreCase("Dvds")) {

                    String[] firstRowContent = new String[3];
                    for (int j = 0; j < table.getColumnCount(); j++) {
                        String stringText = table.getCellByPosition(j, 0).getDisplayText().trim();

                        if (j < 3) {
                            firstRowContent[j] = stringText;
                        }
                    }

                    for (int j = 1; j < table.getRowCount(); j++) {
                        Dvd dvd = new Dvd();
                        for (int k = 0; k < table.getColumnCount(); k++) {
                            String stringText = table.getCellByPosition(k, j).getDisplayText().trim();

                            String dvdAtr = firstRowContent[k];

                            if (dvdAtr.equalsIgnoreCase("Title")) {
                                dvd.setTitle(stringText);
                            } else if (dvdAtr.equalsIgnoreCase("Type")) {
                                dvd.setType(DvdType.valueOf(stringText));
                            } else if (dvdAtr.equalsIgnoreCase("Content")) {
                                Set<Movie> moviesToDvd = new HashSet<Movie>();

                                String[] moviesRef = stringText.split(",");

                                if (moviesRef.length == 1 && moviesRef[0].trim().isEmpty()) {
                                    dvd.setContent(moviesToDvd);
                                } else {
                                    for (String s : moviesRef) {
                                        String[] nameAndYear = s.split("\\(");
                                        if (nameAndYear.length == 1) {
                                            Movie newMovie = new Movie();
                                            newMovie.setName(nameAndYear[0].trim());
                                            moviesToDvd.add(newMovie);
                                        } else {
                                            Movie newMovie = new Movie();
                                            newMovie.setName(nameAndYear[0].trim());
                                            newMovie.setYear(Integer.parseInt(nameAndYear[1].replace(')', ' ').trim()));
                                            moviesToDvd.add(newMovie);
                                        }
                                    }
                                    dvd.setContent(moviesToDvd);
                                }
                            }
                        }

                        dvds.add(dvd);
                    }

                }

                if (table.getTableName().equalsIgnoreCase("Movies")) {
                    String[] firstRowContent = new String[6];
                    for (int j = 0; j < table.getColumnCount(); j++) {
                        String stringText = table.getCellByPosition(j, 0).getDisplayText().trim();

                        if (j < 6) {
                            firstRowContent[j] = stringText;
                        }
                    }

                    for (int j = 1; j < table.getRowCount(); j++) {
                        Movie movie = new Movie();
                        for (int k = 0; k < table.getColumnCount(); k++) {
                            String stringText = table.getCellByPosition(k, j).getDisplayText().trim();

                            String movieAtr = firstRowContent[k];

                            if (movieAtr.equalsIgnoreCase("Name")) {
                                movie.setName(stringText);
                            } else if (movieAtr.equalsIgnoreCase("Director")) {
                                movie.setDirector(stringText);
                            } else if (movieAtr.equalsIgnoreCase("Year")) {
                                movie.setYear(Integer.parseInt(stringText));
                            } else if (movieAtr.equalsIgnoreCase("Country")) {
                                movie.setCountry(stringText);
                            } else if (movieAtr.equalsIgnoreCase("Actors")) {
                                Set<String> actorsToMovie = new HashSet<String>();

                                String[] actorsRef = stringText.split(",");

                                if (actorsRef.length == 1 && actorsRef[0].isEmpty()) {
                                    movie.setActors(actorsToMovie);
                                } else {
                                    for (String s : actorsRef) {
                                        actorsToMovie.add(s.trim());
                                    }
                                    movie.setActors(actorsToMovie);
                                }
                            } else if (movieAtr.equalsIgnoreCase("Genres")) {
                                Set<Genre> genresToMovie = new HashSet<Genre>();

                                String[] genresRef = stringText.split(",");

                                if (genresRef.length == 1 && genresRef[0].isEmpty()) {
                                    movie.setGenres(genresToMovie);
                                } else {
                                    for (String s : genresRef) {
                                        genresToMovie.add(Genre.valueOf(s.trim()));
                                    }
                                    movie.setGenres(genresToMovie);
                                }
                            }
                        }

                        movies.add(movie);
                    }
                }
            }

            importToDatabase(dvds, movies);
        } catch (RuntimeException ex) {
            throw new ImportFailedException(ex);
        }
    }

    private void importToDatabase(List<Dvd> dvds, List<Movie> movies) {
        MovieManager mm = new MovieManagerImpl();
        DvdManager dm = new DvdManagerImpl();

        Set<Movie> moviesSet = new HashSet<Movie>();
        moviesSet.addAll(movies);

        for (Movie m : moviesSet) {
            mm.add(m);
        }

        for (Dvd d : dvds) {
            Set<Movie> moviesOfDvd = d.getContent();
            Set<Movie> newContent = new HashSet<Movie>();

            for (Movie m : moviesSet) {
                if (moviesOfDvd.contains(m)) {
                    newContent.add(m);
                }
            }

            d.setContent(newContent);
            dm.add(d);
        }
    }
}
